博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
17-1 djanjo进阶-路由,视图,模板
阅读量:5080 次
发布时间:2019-06-13

本文共 11363 字,大约阅读时间需要 37 分钟。

一 路由系统进阶(urls.py)

 动态路由

urls.py中通过正则表达式的分组匹配,捕获用户访问的url中的值,传递给视图函数

1 分组匹配(通过圆括号):
相当于给视图函数传递 位置参数

例子:

1 from django.conf.urls import url 2  3 from . import views 4  5 urlpatterns = [ 6     url(r'^articles/2003/$', views.special_case_2003), 7     url(r'^articles/([0-9]{4})/$', views.year_archive), 8     url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), 9     url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),10 ]

 

2 分组命名匹配:

相当于给视图函数传递 关键字参数

在Python的正则表达式中,分组命名正则表达式组的语法是(?P<name>pattern),其中name是组的名称,pattern是要匹配的模式。

例子:

1 from django.conf.urls import url 2  3 from . import views 4  5 urlpatterns = [ 6     url(r'^articles/2003/$', views.special_case_2003), 7     url(r'^articles/(?P
[0-9]{4})/$', views.year_archive), 8 url(r'^articles/(?P
[0-9]{4})/(?P
[0-9]{2})/$', views.month_archive), 9 url(r'^articles/(?P
[0-9]{4})/(?P
[0-9]{2})/(?P
[0-9]{2})/$', views.article_detail),10 ]

3 name

防止将url硬编码到我们的业务逻辑代码中,给url起别名

通过别名,反向找到 url

配置:

在views.py中:

from django.urls import reverse
具体的url = reverse('url别名')

例子:

urls.py里面配置:

url(r'^publisher_list/$', views.publisher_list, name="alex")

vivews.py引用:

# def edit_publisher(request, edit_id):#     print(reverse('alex'))#     print("=" * 120)#     if request.method == "POST":#         new_name = request.POST.get("name888")#         # 去数据库修改出版社名字#         obj = models.Publisher.objects.get(id=edit_id)#         obj.name = new_name#         obj.save()#         return redirect(reverse('alex')) #返回一个url#     print(edit_id)#     publisher_obj = models.Publisher.objects.get(id=edit_id)#     return render(request, "edit_publisher.html", {"obj": publisher_obj})

4 传参数的两种写法(一不小心就被坑了)

例子一:url传参

1 urls.py配置:

url(r'^edit_publisher/$', views.edit_publisher),

2 views.py 

3 def edit_publisher(request):     if request.method=="POST": 4         #获取用户更改的id 5         edit_id=request.POST.get("id")#从浏览器传的参数获取的id 6         new_name=request.POST.get("name")#从form表单获取的名字 7         #去数据库找到这条记录 8         obj=models.Publisher.objects.get(id=edit_id) 9         obj.name=new_name10         obj.save()11         return redirect("/publisher_list/")12     else:13         edit_id = request.GET.get("id")14         publisher_edit = models.Publisher.objects.get(id=edit_id)15         return render(request,"edit_publisher.html",{"obj":publisher_edit})

注意:#上面红色字体里面的的obj一定要和你相应的edit_publisher里面的value,里面的一致,比如value=obj.name 这里就一定用obj

3 html配置:

publisher_list.html

1  2  3  4     
5 出版社列表 6
7 8 9
10
11
12
13
14
15
16
17
18
19 20 {
# data这里一定要跟views里面的data一样#}21 {% for publisher in data %}22
23
24
25
26
33
34 {% endfor %}35
# id 出版社名字 操作
{ { forloop.counter }} { { publisher.id }} { { publisher.name }} 27 { # 这是动态传参#}28 { # 编辑#}29 { # 这是浏览器传参数#}30 编辑31 删除32
36 37
38
39
40 41 42
View Code

edit_publisher.html

1  2  3  4     
5 编辑 6
7 8 9
10
11
12
13
14
16
17
18 19
20
21
22
23
24
25 26 27
View Code

例子二 动态传参

1 urls配置:

url(r'^edit_publisher/(\d+)/$', views.edit_publisher),

2 views.py配置

1 # def edit_publisher(request,edit_id): 2 #     if request.method=="POST": 3 #             #获取用户更改的id 4 # 5 #             new_name=request.POST.get("name")#从form表单获取的名字 6 #             #去数据库找到这条记录 7 #             obj=models.Publisher.objects.get(id=edit_id) 8 #             print(obj.name) 9 #             obj.name=new_name10 #             obj.save()11 #             return redirect("/publisher_list/")12 #     else:13 #14 #         publisher = models.Publisher.objects.get(id=edit_id)15 #         return render(request,"edit_publisher.html",{"obj":publisher})

3 html配置:

publisher_list.html

edit_publisher.html不变

 

 

二 视图函数进阶(views.py)

1. 1-views.py

 1.基础必会三件套
  1. HttpResponse('字符串')
  2. render(request, "xx.html", {"key": value})
  3. redirect("/其它的url/")

2. FBV(Function Base View) 基于函数的视图

  通过request.method == "POST" 去判断

例子:

1 # def edit_publisher(request, edit_id): 2 #     print(reverse('alex')) 3 #     print("=" * 120) 4 #     if request.method == "POST": 5 #         new_name = request.POST.get("name888") 6 #         # 去数据库修改出版社名字 7 #         obj = models.Publisher.objects.get(id=edit_id) 8 #         obj.name = new_name 9 #         obj.save()10 #         return redirect(reverse('alex'))11 #     print(edit_id)12 #     publisher_obj = models.Publisher.objects.get(id=edit_id)13 #     return render(request, "edit_publisher.html", {"obj": publisher_obj})

3. CBV(Class Base View) 基于类的视图

  1. 必须继承views.View -->在views.py里面导入: from django import views
  2. 写一个自己的视图类
  3. 通过定义不同的方法,来处理用户不同的请求
  4. 在urls.py中注册视图的时候要写 views.类名.as_view()

urls.py中配置:

url(r'^edit_publisher/(?P
\d+)/$', views.EditPublisher.as_view(), name="wusir"),

view.py配置:

例子:

1 class EditPublisher(views.View): 2     def get(self, request, edit_id): 3         publisher_obj = models.Publisher.objects.get(id=edit_id) 4         return render(request, "edit_publisher.html", {
"obj": publisher_obj}) 5 6 def post(self, request, edit_id): 7 new_name = request.POST.get("name888") 8 # 去数据库修改出版社名字 9 obj = models.Publisher.objects.get(id=edit_id)10 obj.name = new_name11 obj.save()12 return redirect(reverse('alex'))

2.1 request对象的常用属性和方法(常用的几个)

request表示的是和用户请求相关的所有数据

1. request.method --> 用户当前请求的请求方法
2. request.GET --> 用户请求中url中的参数
3. request.POST --> 用户POST请求的数据
4. request.path_info --> 用户访问的url路径是什么

 

3.1 Django上传文件

1. 前端页面

  1. form表单一定要有action,method必须是post
  2. 一定要配置enctype="multipart/form-data
2. 后端:

def upload(request):    """    保存上传文件前,数据需要存放在某个位置。默认当上传文件小于2.5M时,django会将上传文件的全部内容读进内存。从内存读取一次,写磁盘一次。    但当上传文件很大时,django会把上传文件写到临时文件中,然后存放到系统临时文件夹中。    :param request:     :return:     """    if request.method == "POST":        # 从请求的FILES中获取上传文件的文件名,file为页面上type=files类型input的name属性值        filename = request.FILES["file"].name        # 在项目目录下新建一个文件        with open(filename, "wb") as f:            # 从上传的文件对象中一点一点读            for chunk in request.FILES["file"].chunks():                # 写入本地文件                f.write(chunk)        return HttpResponse("上传OK")

 

4.1 JsonResponse

专门用来返回JSON格式数据的响应对象
from django.http import JsonResponse

例子:

from django.http import JsonResponseresponse = JsonResponse({
'foo': 'bar'})print(response.content)b'{"foo": "bar"}'

 默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。

例子:

urls.pyurl(r'^json_test/$', views.JsonTest.as_view()),views.pyclass JsonTest(views.View):    def get(self, request):        res = {
"code": 0, "data": "alex"} res2 = ["alex", "污Sir", "金老板", "小姨妈", "MJJ"] return JsonResponse(res2,safe=False)

 

三 模板引擎进阶

1 模板语法:

  1. 两个语法:

    1. {
{ }} --> 跟变量相关的操作
    2. {% %} --> 跟逻辑相关的操作

  2. 变量相关

    1. 传字典或对象类型的数据 obj.name/obj.age
    2. 传数组类型的数据 obj.索引值

例子:

1 def template_test(request): 2     l = [11, 22, 33] 3     d = {
"name": "alex"} 4 5 class Person(object): 6 def __init__(self, name, age): 7 self.name = name 8 self.age = age 9 10 def dream(self):11 return "{} is dream...".format(self.name)12 13 Alex = Person(name="Alex", age=34)14 Egon = Person(name="Egon", age=9000)15 Eva_J = Person(name="Eva_J", age=18)16 17 person_list = [Alex, Egon, Eva_J]18 return render(request, "template_test.html", {
"l": l, "d": d, "person_list": person_list})

取值:

{
# 取l中的第一个参数 #}{
{ l.0 }}{
# 取字典中key的值 #}{
{ d.name }}{
# 取对象的name属性 #}{
{ person_list.0.name }}{
# .操作只能调用不带参数的方法 #}{
{ person_list.0.dream }}

 

  3. 日期格式化

    <p>{
{ today|date:"Y-m-d H:i:s"}}</p>
  4. 显示真正的html代码
    <p>{
{ link|safe }}</p>

例子:

view配置:

1 def template_test(request): 2     data = ["金老板", "景女神", "MJJ"] 3     # data = "" 4     filesize = 1234567890 5     import datetime 6     today = datetime.datetime.today() 7     link = "" 8  9 10     class Person(object):11         def __init__(self, name, dream):12             self.name = name13             self.dream = dream14 15         def dream(self):16             return "我的梦想是学好Python!"17     pw = Person("彭玮", "不去下一期!")18 19     return render(request, "t.html", {20         "data": data,21         "file_size": filesize,22         "today": today,23         "link": link,24         "person": pw25     })
View Code

html中配置:

1  2  3  4     
5 Title 6 7 8 9 10 {#

{

{ data.1 }}

#}11

{

{ data|default:"暂无数据" }}

12

{

{ file_size|filesizeformat }}

13

{

{ today }}

14 15 16

{

{ link }}

17 {#

{

{ link|safe }}

#}18 19

20 21

22 {% for teacher in data %}23 {% if forloop.last %}24 {

{ teacher }}25 {% else %}26 {
{ teacher }},27 {% endif %}28 {% endfor %}29

30 {#

{% if 3 > 2 > 1 %}{% endif %}

#}(不支持这样写)31 {##}32 {#

{% if 3 > 2 and 2 > 1 %}{% endif %}

#}33 34

35 36 {
{ person.name }}37 {
{ person.dream }}38 39 40 41
View Code

2. 母板

  1. 为什么要用母版?
  不同的页面有大量重复的代码,我们可以把公用的部分提取出来放在单独一个文件
  2. 怎么使用?
  1.1. 在子页面 通过使用 {% extends ‘模板名’ %} --> 放在子页面的最上面
  2. 1{% block xx %}{% endblock %}

母版例子:

1  2  3  4     
5 {<div></div> { html_title }} 6
7 {% block page-css %} 8 9 {% endblock %}10 11 12 {% include 'nav.html' %}13
14
15
16 17 {% block page-main %}18 19 {% endblock %}20 21
22
23
24 25 {% block page-js %}26 27 {% endblock %}28 29
View Code

3. 组件

可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入即可。

  使用 {% include '组件名' %}导入

如何继承母版例子:

1 {% extends 'mama.html' %} 2  3 {% block page-main %} 4 
5
6
7
8
9
10
11
12
13
14 {% for publisher in publisher_list %}15
16
17
18
19
23
24 {% endfor %}25
26
# id 出版社名称 操作
{
{ forloop.counter }}
{
{ publisher.id }}
{
{ publisher.name }}
20 编辑21 删除22
27 28 {% endblock %}29 30 {#我这个页面才用到的一个js文件#}31 {% block page-js %}32 33 {% endblock %}
View Code

 四 CSRF

1. 为什么要有csrf_token?

2. Django中如何使用?
在render的页面上写上{% csrf_token %}
3. 如果是form表单形式提交,必须放在form表单中
4 如果不加csrf_token默认是不让提交的报403错误

例子:

urls.py配置

 1 url(r'^csrf_test/$', views.csrf_test), 

views.py配置:

def csrf_test(request):    if request.method=="POST":        print(request.POST)        return HttpResponse("OK")    else:        return render(request,"csrf_test.html")

html配置:

{
% csrf_token %}

 

转载于:https://www.cnblogs.com/huningfei/p/9465345.html

你可能感兴趣的文章
JavaFX中ObservableValue类型
查看>>
杭电 1097 A hard puzzle
查看>>
[转载]INFORMIX锁机制及如何剖析其锁申辩(第二部门)
查看>>
Andriod-项目stymqjlb-学习笔记2-原型
查看>>
Web AppDomain
查看>>
JQuery创建规范插件
查看>>
AD 域服务简介(三)- Java 对 AD 域用户的增删改查操作
查看>>
Unity中Text渐变色,和Text间距
查看>>
P4932 浏览器
查看>>
Concurrency Kit 0.2.13 发布,并发工具包
查看>>
SQL Relay 0.50 发布,数据库负载均衡器
查看>>
Infinispan 5.3.0.Alpha1 发布
查看>>
设计模式学习笔记——原型模式(Prototype)
查看>>
算法普林斯顿
查看>>
Struts2之类范围拦截器和方法拦截器
查看>>
模型层(练习)
查看>>
XML解析技术研究(一)
查看>>
Qt 学习之路 :使用 QJson 处理 JSON
查看>>
NPOI操作Excel导入导出
查看>>
angularJS 移动端焦点图
查看>>